package cn.dansj.common.utils.http;

import cn.dansj.common.utils.json.JSONUtils;
import cn.dansj.common.utils.json.JSONObject;
import cn.dansj.common.utils.transfer.AssertUtils;
import cn.dansj.common.utils.transfer.StringUtils;
import cn.dansj.common.utils.transfer.Transformation;
import cn.dansj.common.utils.transfer.Verification;

import java.net.URI;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Set;

public abstract class URLUtils {
    /**
     * 获取URL的参数
     *
     * @param url url
     * @param key url中的参数key
     */
    public static String getParam(String url, String key) {
        String params = separateParam(url);
        if (Verification.checkNull(url) || Verification.checkNull(params) || Verification.checkNull(key)) {
            return "";
        }
        String[] arrSplit = params.split("[&]");
        for (String strSplit : arrSplit) {
            String[] arrSplitEqual = strSplit.split("[=]");
            if (arrSplitEqual.length > 1) {
                if (key.equals(arrSplitEqual[0])) {
                    return arrSplitEqual[1];
                }
            }
        }
        return "";
    }

    /**
     * 获取url的参数
     *
     * @param v url
     */
    public static JSONObject getParam(String v) {
        String param = separateParam(v);
        JSONObject json = new JSONObject();
        String[] params = StringUtils.split(param, "&");
        for (String p : params) {
            String[] split1 = StringUtils.split(p, "=");
            if (split1.length == 2) {
                String key = split1[0];
                String value = split1[1];
                json.put(key, JSONUtils.isJSON(value) ? JSONUtils.toJSONObject(value) : value);
            } else {
                json.put(split1[0], StringUtils.EMPTY);
            }
        }
        return json;
    }

    /**
     * 拼接url,将map形式转成url参数
     */
    public static String joinParams(Map<String, ?> params) {
        Set<String> keySet = params.keySet();
        StringBuilder paramsBuilder = new StringBuilder();
        keySet.forEach(e -> {
            final Object o = params.get(e);
            String value;
            if (o instanceof String[]) {
                String[] v = (String[]) o;
                value = v.length > 0 ? v[0] : StringUtils.EMPTY;
            } else {
                value = StringUtils.toString(o);
            }
            paramsBuilder.append(e).append("=").append(value).append("&");
        });

        int length = paramsBuilder.length();

        if (length > 0) paramsBuilder.setLength(length - 1);

        final String pars = paramsBuilder.toString();
        return Verification.checkNull(pars) ? StringUtils.EMPTY : "?" + pars;
    }

    /**
     * 分离参数
     */
    private static String separateParam(String url) {
        if (Verification.checkNull(url)) return StringUtils.EMPTY;
        String[] arrSplit = url.trim().split("[?]");
        return arrSplit.length > 1 ? arrSplit[1] : StringUtils.EMPTY;
    }

    /**
     * 删除url的参数部分
     */
    public static String truncParam(String url) {
        if (Verification.checkNull(url)) return StringUtils.EMPTY;
        return url.trim().split("[?]")[0];
    }

    /**
     * 格式化成标准的url格式
     */
    public static String formatURL(String url) {
        final String formatURL = url.replaceAll("/+", "/").replaceAll("^/*|/*$", "");
        return formatURL.startsWith("http") ? formatURL.replaceFirst("/", "//") : "/" + formatURL;
    }

    /**
     * 去除url首尾的/
     */
    public static String truncLeadingAndTrailingSlashes(String u) {
        return Verification.checkNull(u) ? "" : u.replaceAll("/+", "/").replaceAll("^/*|/*$", "");
    }

    /**
     * 获取url的host信息
     */
    public static String getHost(String url) {
        return URI.create(url).getHost();
    }

    /**
     * URL 解码
     */
    public static String decode(String str) {
        return Transformation.lambdaTryCatch(() -> URLDecoder.decode(str, StandardCharsets.UTF_8.name()), Transformation.emptyStringSupplier);
    }

    /**
     * URL 转码
     */
    public static String encode(String str) {
        return Transformation.lambdaTryCatch(() -> URLEncoder.encode(str, StandardCharsets.UTF_8.name()), Transformation.emptyStringSupplier);
    }

    public static String joinPath(String... path) {
        return String.join("/", path);
    }

    /**
     * 获取完整的host
     */
    public static String getFullHost(String uri) {
        final URI newURI = URI.create(uri);
        final String scheme = newURI.getScheme();
        final String host = newURI.getHost();
        AssertUtils.notNull(host, "uri解析失败：" + uri);
        final int port = newURI.getPort();
        return Transformation.nvl(scheme, "http") + "://" + host + Transformation.lambdaIf(port == -1 || (port == 80 && "http".equals(scheme) || (port == 443 && "https".equals(scheme))), StringUtils.EMPTY, ":" + port);
    }
}
